今天這篇文章,我將介紹Rust中兩個相當有用的資料結構:Vec以及HashMap,Vec可以用來儲存一組數字或是用戶的資訊,而HashMap可以在常數時間複雜度內,快速查詢儲存在其中的內容。
另外,還要傳授如何使用疊代器優雅處理內容。
Vec是Rust常見的資料結構之一,可以把Vec想像成一個清單,可以不斷的將內容插入其中。
用一個範例,讓大家熟悉Vec吧。
如何建立一個Vec,有三種方式:
fn main() {
// 第一種,建立空Vec,之後加入內容
let mut shopping_list: Vec<&str> = Vec::new();
shopping_list.push("蛋糕");
shopping_list.push("小餅乾");
// 第二種,使用Vec!,儲存設定的內容
let numbers = vec![1, 2, 3, 4, 5];
// 第三種,使用Vec!,儲存重複的內容
// 底下的方式可以建立用10個0的Vec,這樣就不用打一堆0
let zeros = vec![0; 10];
// 顯示Vec的內容
println!("購物清單:{:?}", shopping_list);
println!("數字:{:?}", numbers);
println!("十個零:{:?}", zeros);
}
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
// 危險的方式,如果超過範圍會發生panic(程式錯誤,終止)
println!("{:?}",numbers[1]);
// 安全的方式,嘗試取得範圍外的內容,會顯示超出陣列範圍,然後繼續執行後面的程式
if let Some(value) = numbers.get(1) {
println!("取得Vec元素: {}", value);
} else {
println!("超出陣列範圍");
}
}
HashMap就像是一本字典,可以快速在字典裡根據詞(HashMap的Key)找到對應的解釋(HashMap的Key對應的內容)。
接下來,開始建立第一個HashMap吧。
use std::collections::HashMap;
fn main() {
// 第一個方法:各別插入
let mut scores = HashMap::new();
scores.insert("Alan", 10);
scores.insert("Dan", 9);
println!("分數表:{:?}", scores);
// 第二個方法:直接建立
let config = HashMap::from([
("host", "localhost"),
("port", "8080"),
]);
println!("設定:{:?}", config);
}
疊代器用來處理數據,就像是工廠的流水線,將送來的東西一個個做相同的處理。
Map可以把每個元素轉換成你希望的模樣。
下面是Map搭配Vec的使用教學,將未稅的甜甜價轉換成含稅的價格:
fn main() {
let prices = vec![100, 200, 300];
let with_tax: Vec<f64> = prices
.iter()// 使用疊代器
.map(|price| *price as f64 * 1.05) // 從prices取得實際的數值後,轉換成f64,再乘1.05
.collect();// 啟動計算,並將計算後的數值收集起來
println!("含稅價格:{:?}", with_tax);
}
Filter就像一個篩子,只允許滿足特定條件的元素通過。
底下是一個購物網站中的篩選範例,我們將進行篩選後,顯示符合條件的商品:
#[derive(Debug)]
struct Product {
name: String,
price: i32,
in_stock: bool,
}
fn main() {
let products = vec![
Product { name: "筆電".to_string(), price: 30000, in_stock: true },
Product { name: "滑鼠".to_string(), price: 1000, in_stock: false },
Product { name: "鍵盤".to_string(), price: 2000, in_stock: true },
Product { name: "螢幕".to_string(), price: 8000, in_stock: true },
];
// 顯示有庫存(in_stock是true)並且價格小於10000的商品
let filter_result: Vec<&Product> = products
.iter()
.filter(|p| p.in_stock && p.price < 10000)
.collect();
println!("符合條件的商品:");
for product in filter_result {
println!(" - {} : (${:})", product.name, product.price);
}
}
我們在Map和Filter的部分都見到過Collect,可以說有iter的地方最後都會有collect做結尾。collect負責將iter處理後的內容收集起來,放入對應的元素中。